﻿using System;
using System.IO;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using Citi.SecurityWebBrowser;
using EO.WebBrowser;
using EO.WebBrowser.WinForm;

namespace Citi.BOExtraction.Util
{
    public class BusinessObjectsExtract : EOWebBrowserUtil
    {
        public BusinessObjectsExtract(WebControl webControl, string reportName, string startUrl, string singleSignOnUrl, string userLogin, string pathToSave,
            string parameters, bool newWindowNoAction, Form form = null)
            : base(webControl, reportName, startUrl, singleSignOnUrl, userLogin, pathToSave, parameters, newWindowNoAction, form)
        { }

        public virtual string JavascriptFrameBody { get { return "window.frames['headerPlusFrame'].frames['dataFrame'].frames['workspaceFrame'].frames['workspaceBodyFrame']"; } }

        public override void StartExtractionLogged()
        {
            JavascriptRefreshDate = string.Format("{0}.frames['webiViewFrame'].document.getElementById('statusRefDate').innerHTML", JavascriptFrameBody);
            InboxDocumentLoadCompleted();
        }

        public void StartExtraction(bool joinSheets, string newSheetName, string boUrl)
        {
            base.StartExtraction(boUrl);
        }

        private void MergeSheets(string pathToSave, string newSheetName)
        {
            var newFileLocalPath = LocalPathToSave.Replace(Path.GetExtension(LocalPathToSave), ".xlsx");
            var newFilePath = pathToSave.Replace(Path.GetExtension(pathToSave), ".xlsx");

            if (File.Exists(newFileLocalPath)) File.Delete(newFileLocalPath);

            new Helpers.MergeExcel(LocalPathToSave, newFileLocalPath, newSheetName, null, 1, 0).DoMerge();

            if (File.Exists(newFilePath)) File.Delete(newFilePath);
            File.Copy(newFileLocalPath, newFilePath);

            Log(string.Format("File saved on '{0}'", newFilePath));
        }

        public virtual void InboxDocumentLoadCompleted()
        {
            var javascriptMainTable = string.Format("{0}.document.getElementById('ListingURE_listMainTable')", JavascriptFrameBody);
            WebBrowser.WaitUntilExist(javascriptMainTable, 120000);

            Log(string.Format("Looking for report '{0}'", ReportName));

            var javascript = string.Format(
                @"var frameBody = {0};

                var rows = frameBody.document.getElementById('ListingURE_listMainTable').rows;
                var found = '';
    
                for(var i = 1; i < rows.length; i++){{
                    if (rows[i].cells[2].innerHTML.indexOf('{1}') != -1 || rows[i].cells[1].innerHTML.indexOf('{1}') != -1){{
                        var cellHidden = rows[i].cells[rows[i].cells.length - 1];
                        cellHidden.getElementsByTagName('input')[1].click();
                        cellHidden.getElementsByTagName('a')[0].click();
                        found = rows[i].cells[0].innerHTML;
                        break; 
                    }}
                }}

                found;", JavascriptFrameBody, ReportName);

            var found = (string)WebBrowser.EvaluateScript(javascript);

            if (!string.IsNullOrWhiteSpace(found))
            {
                Log("Report found");

                if (!found.ToLower().Contains("excel"))
                    ReportRefreshLoadCompleted();
                else
                {
                    Log("Download will start soon");
                    UpdateFormTitle("Download will start soon");
                }
            }
            else
            {
                Log(string.Format("#Error No report was found named '{0}'", ReportName));
                Environment.Exit(Environment.ExitCode);
            }
        }

        string lastRefreshData;
        string JavascriptRefreshDate;

        void DownloadReport()
        {
            var currentRefreshData = (String)WebBrowser.EvaluateScript(JavascriptRefreshDate);

            Log("Business Objects is refreshing the report");
            while (lastRefreshData == currentRefreshData || string.IsNullOrWhiteSpace(currentRefreshData))
            {
                Application.DoEvents();
                Thread.Sleep(100);

                currentRefreshData = (String)WebBrowser.EvaluateScript(JavascriptRefreshDate);
            }

            Log("Business Objects has been refreshed the report");

            var javascriptLocation = string.Format("{0}.frames['webiViewFrame']", JavascriptFrameBody);
            var javascriptElement = string.Format("{0}.frames['webiViewFrame'].document.getElementById('{1}')", JavascriptFrameBody, "{0}");

            Log("Clicking on 'Document' button");
            ClickButtonMenu(javascriptLocation, javascriptElement, "IconImg_Txt_iconMenu_icon_docMenu");

            Log("Clicking on 'Save as in Computer' button");
            ClickButtonMenu(javascriptLocation, javascriptElement, "iconMenu_menu_docMenu_span_text_saveDocComputerAs");

            var buttonExcelXLSX = "saveDocComputerMenu_span_text_saveXLSX";
            if (Path.GetExtension(PathToSave).ToUpper() == ".XLSX" && WebBrowser.WaitUntilExist(string.Format(javascriptElement, buttonExcelXLSX), 6000, false))
            {
                Log("Clicking on 'Excel 2007' button");
                ClickButtonMenu(javascriptLocation, javascriptElement, "saveDocComputerMenu_span_text_saveXLSX");
            }
            else
            {
                Log("Clicking on 'Excel' button");
                ClickButtonMenu(javascriptLocation, javascriptElement, "saveDocComputerMenu_span_text_saveXLS");
            }

            Log("Download will start soon");
            UpdateFormTitle("Download will start soon");
        }

        private void ClickButtonMenu(string javascriptLocation, string javascriptElement, string buttonToClick)
        {
            WebBrowser.WaitUntilExist(string.Format(javascriptElement, buttonToClick));
            ClickOnElement(buttonToClick, javascriptLocation, null, null);
        }

        public void ReportRefreshLoadCompleted()
        {
            startParametersWindows = DateTime.Now;
            var timerParametersWindow = new System.Timers.Timer { Interval = 2000 };
            Log("Looking for 'Run Query' button");
            timerParametersWindow.Elapsed += timerParametersWindow_Elapsed;
            timerParametersWindow.Start();

            WebBrowser.WaitUntilExist(JavascriptRefreshDate, 24000000);

            lastRefreshData = (String)WebBrowser.EvaluateScript(JavascriptRefreshDate);
            DownloadReport();
        }

        #region When parameters windows shows

        DateTime startParametersWindows;
        bool buttonSubmitQueryFound;

        void timerParametersWindow_Elapsed(object sender, ElapsedEventArgs e)
        {
            var buttonId = "theBttnCenterImgpromptsOKButton";
            var location = string.Format("{0}.{1}", JavascriptFrameBody, "frames['webiViewFrame']");
            var javascriptButtonRunQuery = string.Format("{0}.document.getElementById('{1}')", location, buttonId);
            buttonSubmitQueryFound = false;

            try
            {
                buttonSubmitQueryFound = WebBrowser.AllElementExist(javascriptButtonRunQuery);
            }
            catch { }

            if (!buttonSubmitQueryFound && (DateTime.Now - startParametersWindows).TotalSeconds <= 120)
                return;

            if (!buttonSubmitQueryFound && (DateTime.Now - startParametersWindows).TotalSeconds > 120)
            {
                ((System.Timers.Timer)sender).Stop();
                Log("'Run Query' Button not found");
                return;
            }

            Log("Button found");
            ((System.Timers.Timer)sender).Stop();

            //Parameters
            if (!string.IsNullOrWhiteSpace(Parameters))
                FillParameters();

            Wait(2000);

            var realButtonId = "theRealBttnpromptsOKButton";
            WebBrowser.EvaluateScript(string.Format("{0}.disabled = false;", string.Format("{0}.document.getElementById('{1}')", location, realButtonId)));
            WebBrowser.EvaluateScript(string.Format("{0}.disabled = false;", javascriptButtonRunQuery));

            ClickOnElement(realButtonId, location, null, null);
        }

        private void FillParameters()
        {
            Log("Getting report parameters");
            var parameters = GetParametersDictionary();

            var location = string.Format("{0}.{1}", JavascriptFrameBody, "frames['webiViewFrame']");
            var queryParameter = @"
                    function clickParameterGetIndex(parameterName){{
                        var parameters = {0}.document.getElementsByClassName('promptSelected');

                        var id = '';

                        for(var i = 1; i < parameters.length; i++){{
                            if (parameters[i].innerHTML.indexOf(parameterName) != -1){{
                                id = parameters[i];
                            }}
                        }}

                        parameters = {0}.document.getElementsByClassName('promptNormal');

                        for(var i = 1; i < parameters.length; i++){{
                            if (parameters[i].innerHTML.indexOf(parameterName) != -1){{
                                id = parameters[i];
                            }}
                        }}

                        id.click();

                        return eval(id.id.replace('_CWpromptstrLstElt','')) + 1;
                    }}

                    var index = clickParameterGetIndex('{1}');
                    var input = '';
                    
                    input = {0}.document.getElementById('PV' + index);
                    
                    if (input == undefined || input == null || (input != null && input.type == 'hidden')){{
                        input = {0}.document.getElementById('LPV' + index);
                    }}

                    if (input == undefined || input == null || (input != null && input.type == 'hidden')){{
                        input = {0}.document.getElementById('LPV' + index + '_textField');
                    }}

                    if (input == undefined || input == null || (input != null && input.type == 'hidden')){{
                        input = {0}.document.getElementById('PV' + index + 'EnterValue');
                    }}

                    if (Object.prototype.toString.call(input) == '[object HTMLTableElement]'){{
	                    var trs = {0}.document.getElementById('mlst_bodyLPV' + index + '_lov').getElementsByTagName('tr');
	
	                    for(var i = 0; i < trs.length; i++){{
		                    if (trs[i].getElementsByTagName('td')[0].getElementsByTagName('div')[0].innerHTML == '{2}'
                                || trs[i].getElementsByTagName('td')[1].getElementsByTagName('div')[0].innerHTML == '{2}'){{
			                    var o = {0}.frames['DlgFrame']._widgets[trs[i].parentNode.parentNode.parentNode.parentNode.parentNode._widget];

			                    o.internalSelect(i, false, false)
			                    break;
		                    }}
	                    }}

                        {0}.document.getElementById('theBttnIconPV1AddButton').click();

                        return;
                    }}                   

                    input.value = '{2}';

                    var addButton = {0}.document.getElementById('PV' + index + 'AddButton');
                    addButton.click();";

            foreach (var parameter in parameters)
            {
                Log(string.Format("Parameter '{0}'. Value: '{1}'", parameter.Key, parameter.Value));
                WebBrowser.EvaluateScript(string.Format(queryParameter, location, parameter.Key, parameter.Value));

                Wait(2000);
            }

            Wait(1500);
        }

        #endregion
    }
}
